/*
 * Copyright (C) 2012 rothens
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package rpg.entities;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import rpg.game.SingleGame;
import rpg.Location;

/**
 *
 * @author rothens
 */
public final class EntityHandler {

    private Map<String, CopyOnWriteArraySet<Entity>> activeEntities = new ConcurrentHashMap<String, CopyOnWriteArraySet<Entity>>();
    private static final EntityHandler instance = new EntityHandler();

    public static EntityHandler getInstance() {
        return instance;
    }

    private EntityHandler() {
    }

    public Entity createEntity(char type, Location loc) {
        Entity entity = null;

        switch (type) {
            case '*':
                Player.newInstance(loc, SingleGame.getInstance());
                entity = Player.getInstance();
                Dog d = new Dog(loc.getPossibleLocation(loc.getMap()), (LivingEntity)entity);
                addEntity(loc.getMap().getMapName(), d);
                loc.getMap().entities.add(d);
                break;
            case 'r':
                entity = new Rooster(loc);
                break;
            case 'c':
                entity = new Chick(loc);
                break;
            case 'z':
                entity = new ZombiePunk(loc);
                break;
            case 'h':
                entity = new Cat(loc);
                break;
            case 'k':
                entity = new Ram(loc);
                break;
        }
        if (entity != null) {
            addEntity(loc.getMap().getMapName(), entity);
        }
        return entity;
    }

    public synchronized void addEntity(String map, Entity entity) {
        CopyOnWriteArraySet<Entity> curr = activeEntities.get(map);
        if (curr == null) {
            curr = new CopyOnWriteArraySet<Entity>();
        }
        curr.add(entity);
        activeEntities.put(map, curr);

    }

    public synchronized void removeEntity(Entity e) {
        if (e == null || e.getMap() == null) {
            return;
        }
        String name = e.getMap().getMapName();
        CopyOnWriteArraySet<Entity> curr = activeEntities.get(name);
        if (curr != null) {
            curr.remove(e);
        }
        activeEntities.put(name, curr);
        e.getMap().entities.remove(e);

    }

    public synchronized void tick() {

        for (CopyOnWriteArraySet<Entity> map : activeEntities.values()) {
            Iterator<Entity> it = map.iterator();
            while (it.hasNext()) {
                Entity e = it.next();
                if (SingleGame.getInstance().isPaused() && !(e instanceof Player)) {
                    continue;
                }

                if (!e.tick()) {
                    it.remove();
                    e.getMap().entities.remove(e);
                }
            }
        }

    }

    public synchronized void tick(String map) {
        CopyOnWriteArraySet<Entity> entities = activeEntities.get(map);
        if (entities == null) {
            return;
        }

        Iterator<Entity> it = entities.iterator();
        while (it.hasNext()) {
            Entity e = it.next();
            if (SingleGame.getInstance().isPaused() && !(e instanceof Player)) {
                continue;
            }

            e.tick();
        }


    }
}
